﻿#include "Nread.h"
#include <fstream>
#include <iomanip>

Nread::Nread(const std::string& path) : filePath(path), currentLineNum(0) {}

bool Nread::readFile() {
    std::ifstream file(filePath);
    if (!file.is_open()) {
        std::cerr << "文件打开失败: " << filePath << std::endl;
        return false;
    }

    std::string line;
    bool headerEnd = false;
    BroadcastEphemeris currentEph;
    int lineCount = 0; // 星历数据行数计数器

    while (std::getline(file, line)) {
        try {
            if (!headerEnd) {
                rawHeaderLines.push_back(line); // 保存原始头文件行
                if (line.find("END OF HEADER") != std::string::npos) {
                    headerEnd = true;
                    continue;
                }
                parseHeaderLine(line);
            }
            else {
                rawEphemerisLines.push_back(line); // 保存原始星历行

                // 处理星历数据（每8行为一组）
                if (lineCount % 8 == 0) {
                    if (lineCount > 0) {
                        // 前一个星历处理完成，添加到数据列表
                        ephemerisData.push_back(currentEph);
                    }
                    currentEph = BroadcastEphemeris(); // 初始化新星历
                    currentLineNum = 0;
                }

                if (currentLineNum == 0) {
                    // 解析星历第一行：PRN、时间和钟差参数
                    currentEph.prn = line.substr(0, 3);
                    currentEph.year = std::stoi(line.substr(4, 4));
                    currentEph.month = std::stoi(line.substr(9, 2));
                    currentEph.day = std::stoi(line.substr(12, 2));
                    currentEph.hour = std::stoi(line.substr(15, 2));
                    currentEph.min = std::stoi(line.substr(18, 2));
                    currentEph.sec = std::stod(line.substr(21, 11));
                    currentEph.SVclockBias = std::stod(line.substr(24, 19));
                    currentEph.SVclockDrift = std::stod(line.substr(43, 19));
                    currentEph.SVclockDriftRate = std::stod(line.substr(70, 19));
                }
                else if (currentLineNum == 1) {
                    // 解析星历第二行
                    currentEph.IODE = std::stod(line.substr(4, 19));
                    currentEph.Crs = std::stod(line.substr(23, 19));
                    currentEph.deltaN = std::stod(line.substr(42, 19));
                    currentEph.M0 = std::stod(line.substr(61, 19));
                }
                else if (currentLineNum == 2) {
                    // 解析星历第三行
                    currentEph.Cuc = std::stod(line.substr(4, 19));
                    currentEph.e = std::stod(line.substr(23, 19));
                    currentEph.Cus = std::stod(line.substr(42, 19));
                    currentEph.sqrtA = std::stod(line.substr(61, 19));
                }
                else if (currentLineNum == 3) {
                    // 解析星历第四行
                    currentEph.toe = std::stod(line.substr(4, 19));
                    currentEph.Cic = std::stod(line.substr(23, 19));
                    currentEph.Omega0 = std::stod(line.substr(42, 19));
                    currentEph.Cis = std::stod(line.substr(61, 19));
                }
                else if (currentLineNum == 4) {
                    // 解析星历第五行
                    currentEph.i0 = std::stod(line.substr(4, 19));
                    currentEph.Crc = std::stod(line.substr(23, 19));
                    currentEph.omega = std::stod(line.substr(42, 19));
                    currentEph.OmegaDot = std::stod(line.substr(61, 19));
                }
                else if (currentLineNum == 5) {
                    // 解析星历第六行
                    currentEph.iDot = std::stod(line.substr(4, 19));
                    currentEph.codesL2 = std::stod(line.substr(23, 19));
                    currentEph.GPSWeek = std::stod(line.substr(42, 19));
                    currentEph.L2Pflag = std::stod(line.substr(61, 19));
                }
                else if (currentLineNum == 6) {
                    // 解析星历第七行
                    currentEph.SVaccuracy = std::stod(line.substr(4, 19));
                    currentEph.SVhealth = std::stod(line.substr(23, 19));
                    currentEph.TGD = std::stod(line.substr(42, 19));
                    currentEph.IODC = std::stod(line.substr(61, 19));
                }
                else if (currentLineNum == 7) {
                    // 解析星历第八行
                    currentEph.transmissionTime = std::stod(line.substr(4, 19));
                    currentEph.fitInterval = std::stod(line.substr(23, 19));
                    // 其他参数可能在后续字段中
                }

                currentLineNum++;
                lineCount++;
            }
        }
        catch (const std::exception& e) {
            std::cerr << "解析错误: " << e.what() << " (行号: " << lineCount + 1 << ")" << std::endl;
            continue;
        }
    }

    // 处理最后一个星历
    if (lineCount > 0 && currentLineNum == 8) {
        ephemerisData.push_back(currentEph);
    }

    file.close();
    return true;
}

void Nread::parseHeaderLine(const std::string& line) {
    if (line.substr(60, 20) == "RINEX VERSION / TYPE") {
        header.version = line.substr(0, 9);
        header.fileType = line.substr(20, 1);
        header.satelliteSystem = line.substr(40, 1);
    }
    else if (line.substr(60, 20) == "PGM / RUN BY / DATE") {
        header.fileProgram = line.substr(0, 20);
        header.fileAgency = line.substr(20, 20);
        header.date = line.substr(40, 20);
    }
    else if (line.substr(60, 20) == "MARKER NAME") {
        header.markerName = line.substr(0, 60);
    }
    else if (line.substr(60, 20) == "MARKER NUMBER") {
        header.markerNumber = line.substr(0, 60);
    }
    else if (line.substr(60, 20) == "OBSERVER / AGENCY") {
        header.observer = line.substr(0, 20);
        header.agency = line.substr(20, 40);
    }
    else if (line.substr(60, 20) == "REC # / TYPE / VERS") {
        header.receiverType = line.substr(20, 20);
        header.receiverNumber = line.substr(0, 20);
    }
    else if (line.substr(60, 20) == "ANT # / TYPE") {
        header.antennaType = line.substr(20, 20);
        header.antennaNumber = line.substr(0, 20);
    }
    else if (line.substr(60, 20) == "APPROX POSITION XYZ") {
        header.antennaPosition[0] = std::stod(line.substr(0, 14));
        header.antennaPosition[1] = std::stod(line.substr(14, 14));
        header.antennaPosition[2] = std::stod(line.substr(28, 14));
    }
    else if (line.substr(60, 20) == "ION ALPHA") {
        for (int i = 0; i < 4; i++) {
            header.ionAlpha[i] = std::stod(line.substr(4 + i * 12, 12));
        }
    }
    else if (line.substr(60, 20) == "ION BETA") {
        for (int i = 0; i < 4; i++) {
            header.ionBeta[i] = std::stod(line.substr(4 + i * 12, 12));
        }
    }
    else if (line.substr(60, 20) == "DELTA-UTC: A0,A1,T,W") {
        header.deltaUTC_A0 = std::stod(line.substr(0, 19));
        header.deltaUTC_A1 = std::stod(line.substr(19, 19));
        header.deltaUTC_TOW = std::stod(line.substr(38, 19));
        header.deltaUTC_WN = std::stod(line.substr(57, 19));
    }
}

void Nread::parseEphemerisLine(const std::string& line, BroadcastEphemeris& eph) {
    // 此函数在readFile中直接处理，无需单独实现
}

void Nread::displayHeader() const {
    std::cout << "RINEX版本: " << header.version << std::endl;
    std::cout << "文件类型: " << header.fileType << std::endl;
    std::cout << "卫星系统: " << header.satelliteSystem << std::endl;
    std::cout << "程序: " << header.fileProgram << std::endl;
    std::cout << "机构: " << header.fileAgency << std::endl;
    std::cout << "标记名称: " << header.markerName << std::endl;
    std::cout << "天线位置 (X,Y,Z): "
        << header.antennaPosition[0] << ", "
        << header.antennaPosition[1] << ", "
        << header.antennaPosition[2] << std::endl;
    std::cout << "电离层参数 Alpha: "
        << header.ionAlpha[0] << ", "
        << header.ionAlpha[1] << ", "
        << header.ionAlpha[2] << ", "
        << header.ionAlpha[3] << std::endl;
    std::cout << "电离层参数 Beta: "
        << header.ionBeta[0] << ", "
        << header.ionBeta[1] << ", "
        << header.ionBeta[2] << ", "
        << header.ionBeta[3] << std::endl;
}

void Nread::displayEphemeris() const {
    std::cout << "星历数据条数: " << ephemerisData.size() << std::endl;
    for (const auto& eph : ephemerisData) {
        std::cout << "PRN: " << eph.prn << std::endl;
        std::cout << "时间: " << eph.year << "-" << eph.month << "-" << eph.day
            << " " << eph.hour << ":" << eph.min << ":" << eph.sec << std::endl;
        std::cout << "卫星钟差: " << eph.SVclockBias << std::endl;
        std::cout << "轨道参数: sqrtA=" << eph.sqrtA << ", e=" << eph.e << ", M0=" << eph.M0 << std::endl;
        std::cout << "------------------------" << std::endl;
    }
}

void Nread::displayDetailedEphemeris() const {
    std::cout << "星历数据条数: " << ephemerisData.size() << std::endl;
    for (const auto& eph : ephemerisData) {
        std::cout << "\n=== 卫星 " << eph.prn << " 详细星历数据 ===" << std::endl;
        std::cout << std::fixed << std::setprecision(12); // 设置精度

        std::cout << "时间: " << eph.year << "-" << eph.month << "-" << eph.day
            << " " << eph.hour << ":" << eph.min << ":" << eph.sec << std::endl;

        std::cout << "卫星钟参数:" << std::endl;
        std::cout << "  SVclockBias: " << eph.SVclockBias << std::endl;
        std::cout << "  SVclockDrift: " << eph.SVclockDrift << std::endl;
        std::cout << "  SVclockDriftRate: " << eph.SVclockDriftRate << std::endl;

        std::cout << "轨道参数:" << std::endl;
        std::cout << "  IODE: " << eph.IODE << std::endl;
        std::cout << "  Crs: " << eph.Crs << std::endl;
        std::cout << "  deltaN: " << eph.deltaN << std::endl;
        std::cout << "  M0: " << eph.M0 << std::endl;
        std::cout << "  Cuc: " << eph.Cuc << std::endl;
        std::cout << "  e: " << eph.e << std::endl;
        std::cout << "  Cus: " << eph.Cus << std::endl;
        std::cout << "  sqrtA: " << eph.sqrtA << std::endl;
        std::cout << "  toe: " << eph.toe << std::endl;
        std::cout << "  Cic: " << eph.Cic << std::endl;
        std::cout << "  Omega0: " << eph.Omega0 << std::endl;
        std::cout << "  Cis: " << eph.Cis << std::endl;
        std::cout << "  i0: " << eph.i0 << std::endl;
        std::cout << "  Crc: " << eph.Crc << std::endl;
        std::cout << "  omega: " << eph.omega << std::endl;
        std::cout << "  OmegaDot: " << eph.OmegaDot << std::endl;
        std::cout << "  iDot: " << eph.iDot << std::endl;

        std::cout << "其他参数:" << std::endl;
        std::cout << "  codesL2: " << eph.codesL2 << std::endl;
        std::cout << "  GPSWeek: " << eph.GPSWeek << std::endl;
        std::cout << "  L2Pflag: " << eph.L2Pflag << std::endl;
        std::cout << "  SVaccuracy: " << eph.SVaccuracy << std::endl;
        std::cout << "  SVhealth: " << eph.SVhealth << std::endl;
        std::cout << "  TGD: " << eph.TGD << std::endl;
        std::cout << "  IODC: " << eph.IODC << std::endl;
        std::cout << "  transmissionTime: " << eph.transmissionTime << std::endl;
        std::cout << "  fitInterval: " << eph.fitInterval << std::endl;

        std::cout << "=====================================" << std::endl;
    }
}

const Header& Nread::getHeader() const {
    return header;
}

const std::vector<BroadcastEphemeris>& Nread::getEphemerisData() const {
    return ephemerisData;
}

const std::vector<std::string>& Nread::getRawHeaderLines() const {
    return rawHeaderLines;
}

const std::vector<std::string>& Nread::getRawEphemerisLines() const {
    return rawEphemerisLines;
}